package com.dragonwu;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.util.FileCopyUtils;

import java.nio.charset.StandardCharsets;

/**
 * @author DragonWu
 * @since 2022-10-11 10:14
 **/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启权限访问注解
@EnableResourceServer //开启资源服务器
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    //允许匿名访问的
    private static final String[] ALLOW_ASK = {
            "/login",//管理员登录
            "/user/login",//用户登录
            "/captcha",//验证码
    };
    //总数允许访问的
    private static final String[] ALWAYS_ALLOW_ASK = {
            "/v2/api-docs",
            "/swagger-resources/configuration/ui",//用来获取支持的动作
            "/swagger-resources",//用来获取api-docs的URI
            "/swagger-resources/configuration/security",//安全选项
            "/webjars/**",
            "/swagger-ui.html",//以上为api文档接口访问路径
            "**/public/**" //开放访问的资源
    };

    /*
    访问资源配置
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .sessionManagement().disable()
                .authorizeRequests()
                .antMatchers(ALWAYS_ALLOW_ASK).permitAll()
                .antMatchers(ALLOW_ASK).anonymous()
                .antMatchers("/**").authenticated()
                .and().headers().cacheControl();
    }

    /*
     设置公钥
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(jwtTokenStore());

    }

    /*
    jwt token存储
     */
    private TokenStore jwtTokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    /*
    公钥解密的token转换器
     */
    @Bean // 放在ioc容器的
    public JwtAccessTokenConverter accessTokenConverter() {
        //resource 验证token（公钥） authorization 产生 token （私钥）
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        String s = null;
        try {
            ClassPathResource classPathResource = new ClassPathResource("keys/public.key");
            byte[] bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
            s = new String(bytes, StandardCharsets.UTF_8);
        } catch (Exception ignored) {
        }
        tokenConverter.setVerifierKey(s);
        return tokenConverter;
    }
}
